//FYI: https://github.com/Tencent/puerts/blob/master/doc/unity/manual.md

import FairyEditor = CS.FairyEditor;

const App = FairyEditor.App;

function get_package_all_depends(pkg: FairyEditor.FPackage) : string[] {
    let query = new FairyEditor.DependencyQuery();
    query.QueryDependencies(pkg.items, FairyEditor.DependencyQuery.SeekLevel.ALL);
    let set: string[] = [];
    const list = query.resultList;
    for (let index = 0; index < list.Count; index++) {
        const item = list.get_Item(index);
        const name = item.item.owner.name;
        if (set.indexOf(name) === -1)
            set.push(name);
    }
    const name = pkg.name;
    const index = set.indexOf(name);
    if (index >= 0)
        set.splice(index, 1)
    return set;
}

function list_all_circle_depends(pkg: FairyEditor.FPackage, dep: string): void {
    let query = new FairyEditor.DependencyQuery();
    query.QueryDependencies(pkg.items, FairyEditor.DependencyQuery.SeekLevel.ALL);
    const list = query.resultList;
    for (let index = 0; index < list.Count; index++) {
        const item = list.get_Item(index);
        if (item.item.owner.name == dep) {
            console.warn(`${pkg.name} is depend ${item.item.name} in ${dep}`);
        }
    }
}

function check_circle_depends() {
    const packages = App.project.allPackages;
    let map = new Map<string, string[]>();
    let keys: string[] = [];
    for (let index = 0; index < packages.Count; index++) {
        const pkg = packages.get_Item(index);
        keys.push(pkg.name);
        map.set(pkg.name, get_package_all_depends(pkg))
    }

    for (const key of keys) {
        const value = map.get(key);
        console.log(`package :${key} depends on {${value.join(',')}}`)
        for (const dep of value) {
            if (map.has(dep) && map.get(dep).indexOf(key) !== -1) {
                console.error(`package ${key} is circle depends with ${dep}`);
                list_all_circle_depends(App.project.GetPackageByName(key), dep);
            }
        }
    }
    console.log('check completed!')
}

const editMenu = App.menu.GetSubMenu("tool")
editMenu.AddItem("检查循环依赖", "check_all_depences", 1, false, check_circle_depends);

function onDestroy() {
    editMenu.RemoveItem("check_all_depences")
}

export {onDestroy}